package com.zwl.smartplatform.service.impl;

import com.zwl.smartplatform.cache.CategoryCache;
import com.zwl.smartplatform.events.CategoryChangeEvent;
import com.zwl.smartplatform.exceptions.AddDataException;
import com.zwl.smartplatform.exceptions.DeleteDataException;
import com.zwl.smartplatform.exceptions.QueryDataException;
import com.zwl.smartplatform.exceptions.ResultCode;
import com.zwl.smartplatform.mapper.CategoryMapper;
import com.zwl.smartplatform.pojo.Category;
import com.zwl.smartplatform.pojo.CheckType;
import com.zwl.smartplatform.pojo.User;
import com.zwl.smartplatform.service.CategoryService;
import com.zwl.smartplatform.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional//控制事务
public class CategoryServiceImpl implements CategoryService {

    private ApplicationContext context;

    @Autowired
    public void setContext(ApplicationContext context) {
        this.context = context;
    }

    private CategoryMapper categoryMapper;

    private CategoryCache categoryCache;

    @Autowired
    public void setCategoryCache(CategoryCache categoryCache) {
        this.categoryCache = categoryCache;
    }

    @Autowired
    public void setCategoryMapper(CategoryMapper categoryMapper) {
        this.categoryMapper = categoryMapper;
    }

    @Override
    public void addCategory(Category category) {
        Assert.isTrue(!category.isEmpty(CheckType.ADD), ()->{
            throw new  AddDataException("传递的数据不完整，请检查", ResultCode.USERNAME_NULL);
        });
        //这个分类如果存在这么办
        Category currentCategory = categoryMapper.selectByName(category.getCategoryName());
        Assert.isNull(currentCategory,()->{
            throw new AddDataException("分类已经存在",ResultCode.DATA_ALREADY_EXIST);
        });
        //设置创建的时间  当前时间
        category.setCreateTime(new Date());
        //谁创建的  应该是当前登录到用户
        //当前登录用户如何获取到
        //如何xxx 怎么知道 这样到问题代表着一定有一个地方到数据保存了我们想要到东西
        //我们经过分析发现数据保存到session中 需要从session中获取
        //怎么拿到session session
        //TODO session不能通过当前方法到参数传递 会导致接口污染（这个业务本身到数据和你传递的另外一个数据没有关系）
        //如何获取到session session可以通过request获取 request在哪？
        User user = SecurityUtils.getUser();
        category.setCreateBy(user.getUsername());
        categoryMapper.addCategory(category);
        //发送了一个事件 说明当前这个事件发生了
        context.publishEvent(new CategoryChangeEvent());
    }

    @Override
    public int updateCategory(Category category) {
        return 0;
    }

    @Override
    public Category selectById(Long cId) {
        Assert.isTrue(cId>0,()->{
            throw new QueryDataException("主键超出允许到范围",ResultCode.ID_NOT_ALLOWED);
        });
        Category category = categoryCache.getValue(cId);
        return category;
    }

    @Override
    public List<Category> selectAllCategories() {
        //List<Category> categoryList = categoryMapper.selectAllEnableCategories();
        //我们发现分类到数据是不怎么变化到 我们每次查询到数据库结果都是一样到 name就没必要查询数据库
        //按照之前到套路 我们可以吧数据放到缓存中
        List<Category> categoryList = categoryCache.getAllData();
        return categoryList;
    }

    @Override
    public List<Category> selectCategoriesByNameLike(String cName) {
        Assert.hasText(cName,()->{
            throw new QueryDataException("分类名为空",ResultCode.QUERY_PARAM_EMPTY);
        });
        List<Category> categoryList = categoryCache.getAllData();
        //遍历所有到数据 如果当前分类到名字中包含我们到查询条件 则就是我们需要到数据
        List<Category> List = categoryList.stream().filter(category -> category.getCategoryName().contains(cName))
                .collect(Collectors.toList());
        return List;
    }

    @Override
    public int deleteCategoriesByIds(List<Long> ids) {
        Assert.notEmpty(ids,()->{
              throw new DeleteDataException("没有传递id",ResultCode.ID_NULL);
        });
        int result = categoryMapper.deleteCategoriesByIds(ids);
        //发布事件 更新缓存
        context.publishEvent(new CategoryChangeEvent());
        return result;
    }
}
